package com.wx.service.impl;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSONObject;
import com.wx.core.vo.JsapiTicket;
import com.wx.entity.SysWxuser;
import com.wx.service.SysWxTokenService;
import com.wx.service.SysWxuserService;
import com.wx.service.WxJsapiTicketService;
import com.zyht.common.util.HttpUtils;
import com.zyht.redis.service.RedisService;

@Service("WxJsapiTicketService")
public class WxJsapiTicketServiceImpl implements WxJsapiTicketService {

	private Logger logger = LoggerFactory.getLogger(getClass());
	
	private final String jsapiTicketKey = "com.zyht.wechat.JsapiTicketKey";
	
	@Resource
	private RedisService redisService;
	
	@Resource
	private SysWxTokenService sysWxTokenService;

	@Resource
	private SysWxuserService sysWxuserService;


	/**
	 * @Title: GetJsapiTicket
	 * @Date: 2015-3-17
	 * @Autor: gavin
	 * @param @return
	 * @param @throws Exception 设定文件
	 * @return JsapiTicketBean 返回类型
	 * @throws
	 */
	@Override
	public JsapiTicket createJsapiTicket(HttpServletRequest request,String wxid) throws Exception{
		JsapiTicket jsapiTicket = new JsapiTicket();
		if(StringUtils.isEmpty(wxid)){
			return jsapiTicket;
		}
		String refererUrl = getRefUrl(request);
        
		// 生成Js签名
		String timestamp = Long.toString(System.currentTimeMillis() / 1000);
		String noncestr = UUID.randomUUID().toString();
		SysWxuser syswxuser = sysWxuserService.selectByWxid(wxid);
		String jsapi_ticket = getJsapiTicketStr(syswxuser);
		String jsapiTicketStr = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + noncestr
				+ "&timestamp=" + timestamp + "&url=" + refererUrl;
		MessageDigest crypt = MessageDigest.getInstance("SHA-1");
		crypt.reset();
		crypt.update(jsapiTicketStr.getBytes("UTF-8"));
		String signature = com.wx.util.StringUtils.byteToHex(crypt.digest());
		if(syswxuser == null)
			return jsapiTicket;
		jsapiTicket.setAppid(syswxuser.getAppid());
		jsapiTicket.setNonceStr(noncestr);
		jsapiTicket.setSignature(signature);
		jsapiTicket.setTimestamp(timestamp + "");

		String wxurl = "http://" + request.getServerName(); // 服务器地址
		if(request.getServerPort() > 0 && request.getServerPort() != 80){
			wxurl = wxurl + ":" + request.getServerPort();
		}
		wxurl = wxurl + request.getContextPath(); // 项目名称
		jsapiTicket.setWxurl(wxurl);

		jsapiTicket.setWxid(wxid);
		return jsapiTicket;
	}

	private String getRefUrl(HttpServletRequest request){

		String refererUrl = request.getScheme()+ "://" + request.getServerName(); 	//服务器地址  
        if(request.getServerPort()>0 && request.getServerPort()!=80){
        	refererUrl=refererUrl+":"+ request.getServerPort();  
        }
        refererUrl=refererUrl+ request.getContextPath();      		//项目名称  
        refererUrl=refererUrl+request.getServletPath();      		//请求页面或其他地址  
        if(!StringUtils.isEmpty(request.getQueryString())){
        	refererUrl+= "?" + (request.getQueryString()); 			//参数  
        }
		return refererUrl;
	}

	/**
	 * @Title: GetJsapiTicket
	 * @Date: 2015-3-17
	 * @Autor: gavin
	 * @param @return
	 * @param @throws Exception 设定文件
	 * @return JsapiTicketBean 返回类型
	 * @throws
	 */
	@Override
	public JsapiTicket createJsapiTicket(HttpServletRequest request,String wxid,
			SysWxuser syswxuser,String accessToken) throws Exception{

		JsapiTicket jsapiTicket = new JsapiTicket();
		if(StringUtils.isEmpty(wxid)){
			return jsapiTicket;
		}
		String strRefererUrl = getRefUrl(request);
		// 生成Js签名
		String timestamp = Long.toString(System.currentTimeMillis() / 1000);
		String noncestr = UUID.randomUUID().toString();
		String jsapi_ticket = getJsapiTicketStr(syswxuser);
		String jsapiTicketStr = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + noncestr
				+ "&timestamp=" + timestamp + "&url=" + strRefererUrl;
		MessageDigest crypt = MessageDigest.getInstance("SHA-1");
		crypt.reset();
		crypt.update(jsapiTicketStr.getBytes("UTF-8"));
		String signature = com.wx.util.StringUtils.byteToHex(crypt.digest());
		if(syswxuser == null)
			return jsapiTicket;
		jsapiTicket.setAppid(syswxuser.getAppid());
		jsapiTicket.setNonceStr(noncestr);
		jsapiTicket.setSignature(signature);
		jsapiTicket.setTimestamp(timestamp + "");

		String wxurl = "http://" + request.getServerName(); // 服务器地址
		if(request.getServerPort() > 0 && request.getServerPort() != 80){
			wxurl = wxurl + ":" + request.getServerPort();
		}
		wxurl = wxurl + request.getContextPath(); // 项目名称
		jsapiTicket.setWxurl(wxurl);

		jsapiTicket.setWxid(wxid);
		return jsapiTicket;
	}

	@Override
	public JsapiTicket createJsapiTicket(String wxid, String refUrl){
		JsapiTicket jsapiTicket = new JsapiTicket();
		
		if(StringUtils.isEmpty(wxid)){
			return jsapiTicket;
		}
		// 生成Js签名
		String timestamp = Long.toString(System.currentTimeMillis() / 1000);
		String noncestr = UUID.randomUUID().toString();
		
		SysWxuser syswxuser = sysWxuserService.selectByWxid(wxid);
		//获取微信jsapi ticket
		String ticket = getJsapiTicketStr(syswxuser);
		
		String signature = "jsapi_ticket=" + ticket + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" + refUrl;
		try{
			signature = Sha1Encryt(signature);
		} catch (NoSuchAlgorithmException e){
			e.printStackTrace();
			return jsapiTicket;
		} catch (UnsupportedEncodingException e){
			e.printStackTrace();
			return jsapiTicket;
		}
		jsapiTicket.setAppid(syswxuser.getAppid());
		jsapiTicket.setNonceStr(noncestr);
		jsapiTicket.setSignature(signature);
		jsapiTicket.setTimestamp(timestamp + "");
		jsapiTicket.setWxid(wxid);
		return jsapiTicket;
	}

	private String getJsapiTicketStr(SysWxuser syswxuser){
		if(syswxuser == null)
			return null;
		String wxid = syswxuser.getWxid();
		String ticket = this.redisService.get(jsapiTicketKey+"."+wxid);
		if(ticket == null){
			synchronized(this){
				ticket = this.redisService.get(jsapiTicketKey);
				if(ticket != null){
					return ticket;
				}
				String accessToken = sysWxTokenService.getAccessToken(wxid, syswxuser.getAppid(),syswxuser.getAppsecretd());
				String requestUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=".concat(accessToken).concat("&type=jsapi");
				String result = HttpUtils.httpsGet(requestUrl);
				JSONObject jsonObject = JSONObject.parseObject(result);
				if(jsonObject == null || jsonObject.getInteger("errcode") != 0){
					logger.error(wxid+"-->获取jsApiTicket异常："+jsonObject.toString());
					return ticket;
				}
				ticket = jsonObject.getString("ticket");
				Long second = Long.valueOf(jsonObject.getString("expires_in").toString());
				this.redisService.setEx(jsapiTicketKey+"."+wxid,second,ticket);
			}
		}
		return ticket;
	}
	
	private String Sha1Encryt(String signature) throws NoSuchAlgorithmException, UnsupportedEncodingException{

		MessageDigest crypt = MessageDigest.getInstance("SHA-1");
		crypt.reset();
		crypt.update(signature.getBytes("UTF-8"));
		signature = com.wx.util.StringUtils.byteToHex(crypt.digest());
		return signature;
	}
}
